/*
 * 作者：Peter Xiang
 * 联系方式：565067150@qq.com
 * 文档: https://github.com/PxGame
 * 创建时间: 2019/10/28 16:10:56
 */

using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using XMLib.Extensions;
using ActionSystem.Core;
using ActionSystem.Core;
using System.Reflection;
using ActionSystem.Core.Utils;

namespace XMLib.AM
{
    /// <summary>
    /// 窗口类型
    /// </summary>
    [Flags]
    public enum ViewType
    {
        None = 0b0000_0000,
        PassiveAction = 0b0000_0001,      
        State = 0b0000_0010,
        StateSet = 0b0000_0100,
        Action = 0b0000_1000,
        Tool = 0b0001_0000,
        Other = 0b0010_0000,
        Frame = 0b0100_0000,
        StateGroup = 0b1000_0000,
        StateGroupSet = 0b0001_0000_0000,
        SyncAnimationPreviewSet = 0b0010_0000_0000,
    }

    /// <summary>
    /// 编辑器配置
    /// </summary>
    [Serializable]
    public partial class ActionEditorSetting
    {
        public int stateSelectIndex = -1;
        public int stateGroupSelectIndex = -1;
        public int attackRangeSelectIndex = -1;
        public int bodyRangeSelectIndex = -1;
        public int actionSelectIndex = -1;
        public int globalActionSelectIndex = -1;
        public int frameSelectIndex = -1;
        public bool enableAllControl = false;
        public bool enableQuickKey = false;

        public ViewType showView;

        public Vector2 otherViewScrollPos = Vector2.zero;

        public float frameWidth = 40;
        public float frameListViewRectHeight = 200f;
        public string aniamtionPath = "Assets/";
        public string actionSystemConfigPath = "";
    }

    /// <summary>
    /// ActionEditorWindow：工具的主窗口
    /// </summary>
    public class ActionEditorWindow : EditorWindow
    {
        [MenuItem("动作编辑器/主编辑器")]
        public static void ShowEditor()
        {
            EditorWindow.GetWindow<ActionEditorWindow>();
        }
        /// <summary>
        /// 显示主窗口
        /// </summary>
        /// <param name="target">针对的目标对象</param>
        /// <param name="config">配置文件</param>
        public static void ShowEditor(GameObject target, TextAsset config)
        {
            
            if (EditorApplication.isPlayingOrWillChangePlaymode)
            {
                Debug.LogWarning("编辑器不能在运行时打开");
                return;
            }

            var win = EditorWindow.GetWindow<ActionEditorWindow>();
            if (win.configAsset != null)
            {
                if (win.configAsset == config)
                {// 如果当前已打开的窗口相同，则focus,并直接返回
                    win.Focus();
                    return;
                }
                /*else
                {
                    //如果不相同，则创建一个新的窗口
                    win = EditorWindow.CreateWindow<ACActionEditorWindow>();
                    win.Show();
                }*/
            }
            if(win.sysConfigAsset==null)
            {
                win.sysConfigAsset = AssetDatabase.LoadAssetAtPath(win.setting.actionSystemConfigPath,typeof(TextAsset)) as TextAsset;
            }
            //更新参数
            win.UpdateTarget(target);
            win.UpdateConfig(config);            
            win.UpdateSysConfig(win.sysConfigAsset);
            #region StateUIDAttrbute    
            StateUIDAttribute.Names = win.GetStateNames;
            StateUIDAttribute.UIDS = win.GetStateUID;
            #endregion

        }
        #region 所有的子窗口
        [NonSerialized] public readonly ActionListView actionListView;
        [NonSerialized] public readonly ActionSetView actionSetView;
        [NonSerialized] public readonly StateGroupListView stateGroupListView;
        [NonSerialized] public readonly StateGroupSetView stateGroupSetView;
        [NonSerialized] public readonly PassiveActionListView globalActionListView;
        [NonSerialized] public readonly PassiveActionSetView globalActionSetView;
        [NonSerialized] public readonly AttackRangeListView attackRangeListView;
        [NonSerialized] public readonly BodyRangeListView bodyRangeListView;
        [NonSerialized] public readonly FrameListView frameListView;
        [NonSerialized] public readonly StateListView stateListView;
        [NonSerialized] public readonly StateSetView stateSetView;
        [NonSerialized] public readonly SyncAnimationPreviewView syncAnimationPreviewView;
        [NonSerialized] public readonly MenuView menuView;
        [NonSerialized] public readonly ToolView toolView;
        #endregion
        //[SerializeReference]
        public List<IView> views { get; private set; }

        private readonly SceneGUIDrawer guiDrawer;
        private readonly QuickButtonHandler quickButtonHandler;

        #region style

        private readonly float space = 3f;
        private readonly float scrollHeight = 13f;
        private readonly float menuViewRectHeight = 26f*2;
        private readonly float stateListViewRectWidth = 150f;
        private readonly float stateSetViewRectWidth = 200f;
        private readonly float bodyRangeListViewRectWidth = 200f;
        private readonly float attackRangeListViewRectWidth = 200f;
        private readonly float actionListViewRectWidth = 180f;
        private readonly float actionSetViewRectWidth = 200f;
        private readonly float globalActionListViewRectWidth = 150f;
        private readonly float globalActionSetViewRectWidth = 200f;
        private readonly float stateGroupListViewRectWidth = 150f;
        private readonly float stateGroupSetViewRectWidth = 200f;
        private readonly float toolViewRectWidth = 200f;
        private readonly float syncAnimationPrewiewViewRectWidth = 400f;
        public float frameWidth => setting.frameWidth;
        public float frameListViewRectHeight => setting.frameListViewRectHeight;

        #endregion style

        #region data

        #region raw data
        /// <summary>
        ///配置编辑器状态文件位置 
        /// </summary>
        protected static string settingPath = "XMLib.AM.ActionEditorWindow";
        /// <summary>
        /// 整个编辑器的中间数据
        /// </summary>
        public ActionEditorSetting setting = new ActionEditorSetting();
        /// <summary>
        /// 配置数据是否发生变化
        /// </summary>
        public bool actionMachineDirty = false;
        /// <summary>
        /// 编辑器是否在运行中
        /// </summary>
        public bool isRunning => EditorApplication.isPlaying;

        public string lastEditorTargetPath = null;
        /// <summary>
        /// 动作编辑器的编辑游戏对象
        /// </summary>
        public GameObject actionMachineObj = null;
        /// <summary>
        /// 动作状态机？用于设定目标obj
        /// </summary>
        public StateMachineTool actionMachine = null;
        /// <summary>
        /// 配置文件的obj，索引配置文件
        /// </summary>
        public TextAsset configAsset = null;
        /// <summary>
        /// 系统配置文件的obj，索引配置文件
        /// </summary>
        public TextAsset sysConfigAsset = null;

        //动画同步
        public List<GameObject> syncAnimationObjcts = new List<GameObject>();
        public List<Transform> syncAnimationObjctsRootBones = new List<Transform>();
        public List<string> syncAnimationNames = new List<string>();

        /// <summary>
        /// 配置数据
        /// </summary>
        [NonSerialized] public MachineConfig config;//SerializeReference 存在bug，先不使用，即无法使用回滚
        [NonSerialized] public ActionSystemConfig sysConfig;//
        #endregion raw data
        /// <summary>
        /// 配置是否正确
        /// </summary>
        public bool isConfigValid => config != null && (isRunning || configAsset != null);
        /// <summary>
        /// 系统配置是否正确
        /// </summary>
        public bool isSysConfigValid => sysConfig != null && (isRunning || sysConfigAsset != null);
        /// <summary>
        /// 是否有动作状态机
        /// </summary>
        public bool isActionMachineValid => actionMachine != null;
        /// <summary>
        /// 当前状态是否有动画
        /// </summary>
        public bool isCurrentAnimationClipValid => null != GetCurrentAnimationClip();
        /// <summary>
        /// 获取和设置选中状态的index
        /// </summary>
        public int stateSelectIndex
        {
            get
            {
                CheckSelectIndex(ref setting.stateSelectIndex, currentStates);
                return setting.stateSelectIndex;
            }
            set
            {
                int oldIndex = setting.stateSelectIndex;
                setting.stateSelectIndex = value;
                CheckSelectIndex(ref setting.stateSelectIndex, currentStates);
                if (oldIndex != value && oldIndex != setting.stateSelectIndex)
                {//当前帧发生改变
                    actionMachineDirty = true;
                }
            }
        }
        /// <summary>
        /// 获取和设置选中攻击范围的index
        /// </summary>
        public int attackRangeSelectIndex
        {
            get
            {
                CheckSelectIndex(ref setting.attackRangeSelectIndex, currentAttackRanges);
                return setting.attackRangeSelectIndex;
            }
            set
            {
                setting.attackRangeSelectIndex = value;
                CheckSelectIndex(ref setting.attackRangeSelectIndex, currentAttackRanges);
            }
        }
        /// <summary>
        /// 获取和设置当前身体范围的index
        /// </summary>
        public int bodyRangeSelectIndex
        {
            get
            {
                CheckSelectIndex(ref setting.bodyRangeSelectIndex, currentBodyRanges);
                return setting.bodyRangeSelectIndex;
            }
            set
            {
                setting.bodyRangeSelectIndex = value;
                CheckSelectIndex(ref setting.bodyRangeSelectIndex, currentBodyRanges);
            }
        }
        /// <summary>
        /// 获取和设置选中状态Action的index
        /// </summary>
        public int actionSelectIndex
        {
            get
            {
                CheckSelectIndex(ref setting.actionSelectIndex, currentActions);
                return setting.actionSelectIndex;
            }
            set
            {
                setting.actionSelectIndex = value;
                CheckSelectIndex(ref setting.actionSelectIndex, currentActions);
            }
        }
        /// <summary>
        /// 获取和设置当前全局Action的index
        /// </summary>
        public int globalActionSelectIndex
        {
            get
            {
                CheckSelectIndex(ref setting.globalActionSelectIndex, currentGlobalActions);
                return setting.globalActionSelectIndex;
            }
            set
            {
                setting.globalActionSelectIndex = value;
                CheckSelectIndex(ref setting.globalActionSelectIndex, currentGlobalActions);
            }
        }
        /// <summary>
        /// 获取和设置当前全局Action的index
        /// </summary>
        public int stateGroupSelectIndex
        {
            get
            {
                CheckSelectIndex(ref setting.stateGroupSelectIndex, currentStateGroups);
                return setting.stateGroupSelectIndex;
            }
            set
            {
                setting.stateGroupSelectIndex = value;
                CheckSelectIndex(ref setting.stateGroupSelectIndex, currentStateGroups);
            }
        }
        /// <summary>
        /// 获取和设置选中帧配置的index
        /// </summary>
        public int frameSelectIndex
        {
            get
            {
                CheckSelectIndex(ref setting.frameSelectIndex, currentFrames);
                return setting.frameSelectIndex;
            }
            set
            {
                int oldIndex = setting.frameSelectIndex;
                setting.frameSelectIndex = value;
                CheckSelectIndex(ref setting.frameSelectIndex, currentFrames);
                if (oldIndex != value && oldIndex != setting.frameSelectIndex)
                {//当前帧发生改变
                    actionMachineDirty = true;
                }
            }
        }
        /// <summary>
        /// 所有的状态
        /// </summary>
        public List<StateItem> currentStates => config?.states;
        /// <summary>
        /// 当前状态帧配置
        /// </summary>
        public List<FrameConfig> currentFrames => currentState?.state.Frames;
        /// <summary>
        /// 当前帧的受击范围配置
        /// </summary>
        public List<RangeConfig> currentBodyRanges => currentFrame?.bodyRanges;
        /// <summary>
        /// 当前帧的攻击范围配置
        /// </summary>
        public List<RangeConfig> currentAttackRanges => currentFrame?.attackRanges;
        /// <summary>
        /// 当前状态actions
        /// </summary>
        public List<BaseStateActionConfig> currentActions => currentState?.state.ActionDatas;
        /// <summary>
        /// 全局的Actions
        /// </summary>
        public List<BasePassiveActionConfig> currentGlobalActions => config?.passiveActions;
        /// <summary>
        /// groups
        /// </summary>
        public List<StateGroup> currentStateGroups => config?.groups;
        /// <summary>
        /// 所有的状态数
        /// </summary>
        public int currentStateCount => currentStates?.Count ?? -1;
        /// <summary>
        /// 当前状态所有的帧配置数
        /// </summary>
        public int currentFrameCount => currentFrames?.Count ?? -1;
        /// <summary>
        /// 当前帧所有的身体范围个数
        /// </summary>
        public int currentBodyRangeCount => currentBodyRanges?.Count ?? -1;
        /// <summary>
        /// 当前帧所有的攻击范围个数
        /// </summary>
        public int currentAttackRangeCount => currentAttackRanges?.Count ?? -1;
        /// <summary>
        /// 当前状态所有的action个数
        /// </summary>
        public int currentActionCount => currentActions?.Count ?? -1;
        /// <summary>
        /// 全局action个数
        /// </summary>
        public int currentGlobalActionCount => currentGlobalActions?.Count ?? -1;
        /// <summary>
        /// group个数
        /// </summary>
        public int currentStateGroupCount => currentStateGroups?.Count ?? -1;
        /// <summary>
        /// 当前状态
        /// </summary>
        public StateItem currentState => GetSelectItem(stateSelectIndex, currentStates);
        /// <summary>
        /// 当前帧配置
        /// </summary>
        public FrameConfig currentFrame => GetSelectItem(frameSelectIndex, currentFrames);
        /// <summary>
        /// 当前帧身体范围
        /// </summary>
        public RangeConfig currentBodyRange => GetSelectItem(bodyRangeSelectIndex, currentBodyRanges);
        /// <summary>
        /// 当前帧攻击范围
        /// </summary>
        public RangeConfig currentAttackRange => GetSelectItem(attackRangeSelectIndex, currentAttackRanges);
        /// <summary>
        /// 当前状态的action
        /// </summary>
        public object currentAction => GetSelectItem(actionSelectIndex, currentActions);
        /// <summary>
        /// 当前全局action
        /// </summary>
        public object currentGlobalAction => GetSelectItem(globalActionSelectIndex, currentGlobalActions);
        /// <summary>
        /// 当前group
        /// </summary>
        public StateGroup currentStateGroup => GetSelectItem(stateGroupSelectIndex, currentStateGroups);

        #region  attack range
        /// <summary>
        /// 获取到指定帧的攻击范围
        /// </summary>
        /// <param name="frameIndex">帧index</param>
        /// <param name="copyNew">是否返回拷贝的值</param>
        /// <returns>返回范围</returns>
        public List<RangeConfig> FindStayAttackRangeStartWith(int frameIndex, bool copyNew = false)
        {
            StateItem state = currentState;
            FrameConfig config = state.state.GetAttackRangesFrame(frameIndex);//拿到配置
            List<RangeConfig> result = copyNew ? config?.CopyAttackRanges() : config?.attackRanges;
            return result;
        }
        /// <summary>
        /// 获取到当前攻击范围
        /// </summary>
        /// <param name="copyNew">是否返回拷贝的值</param>
        /// <returns></returns>
        public List<RangeConfig> FindStayAttackRangeFromCurrent(bool copyNew = false)
        {
            return FindStayAttackRangeStartWith(frameSelectIndex, copyNew);
        }
        /// <summary>
        /// 拷贝当前选中的配置，并设置为当前攻击范围配置。攻击范围不共享之前帧的配置
        /// </summary>
        public void CopyAttackRangeToCurrentFrameIfStay()
        {
            FrameConfig config = currentFrame;
            if (config == null || !config.stayAttackRange)//是否共享之前帧的配置
            {
                return;
            }

            List<RangeConfig> target = FindStayAttackRangeStartWith(frameSelectIndex);
            if (target == null)
            {
                config.attackRanges = new List<RangeConfig>();
                return;
            }

            config.CopyAttackRangeFrom(target);
            config.stayAttackRange = false;
        }

        #endregion

        #region  body range
        /// <summary>
        /// 获取到指定帧的身体范围
        /// </summary>
        /// <param name="frameIndex">帧index</param>
        /// <param name="copyNew">是否返回拷贝的值</param>
        /// <returns>返回范围</returns>
        public List<RangeConfig> FindStayBodyRangeStartWith(int frameIndex, bool copyNew = false)
        {
            StateItem state = currentState;
            FrameConfig config = state.state.GetBodyRangesFrame(frameIndex);
            List<RangeConfig> result = copyNew ? config?.CopyBodyRanges() : config?.bodyRanges;
            return result;
        }
        /// <summary>
        /// 获取到当前身体范围
        /// </summary>
        /// <param name="copyNew">是否返回拷贝的值</param>
        public List<RangeConfig> FindStayBodyRangeFromCurrent(bool copyNew = false)
        {
            return FindStayBodyRangeStartWith(frameSelectIndex, copyNew);
        }
        /// <summary>
        /// 拷贝当前选中的配置，并设置为当前身体范围配置。身体范围不共享之前帧的配置
        /// </summary>
        public void CopyBodyRangeToCurrentFrameIfStay()
        {
            FrameConfig config = currentFrame;
            if (config == null || !config.stayBodyRange)//是否用的之前帧的数据
            {
                return;
            }

            List<RangeConfig> target = FindStayBodyRangeStartWith(frameSelectIndex);
            if (target == null)
            {
                config.bodyRanges = new List<RangeConfig>();
                return;
            }

            config.CopyBodyRangeFrom(target);
            config.stayBodyRange = false;
        }
        #endregion
        /// <summary>
        /// 让index在合法的范围
        /// </summary>
        /// <typeparam name="T">元素类型</typeparam>
        /// <param name="index">判断的index</param>
        /// <param name="list">列表</param>
        /// <returns></returns>

        private int CheckSelectIndex<T>(ref int index, IList<T> list)
        {
            return index = list == null ? -1 : Mathf.Clamp(index, -1, list.Count - 1);
        }

        private T GetSelectItem<T>(int index, IList<T> list) where T : class
        {
            if (index < 0 || null == list || list.Count == 0)
            {
                return null;
            }
            return list[index];
        }
        public float FrameTime
        {
           get
            {
                if(sysConfig==null)
                {
                    return 1.0f / 60;
                }else
                {
                    return sysConfig.FrameTime;
                }
            }
        }
        #endregion data


       /// <summary>
       /// 创建窗口
       /// </summary>
        public ActionEditorWindow()
        {
            views = new List<IView>();
            //各种子窗口
            globalActionListView = CreateView<PassiveActionListView>();
            globalActionSetView = CreateView<PassiveActionSetView>();
            stateGroupListView = CreateView<StateGroupListView>();
            stateGroupSetView = CreateView<StateGroupSetView>();
            actionListView = CreateView<ActionListView>();
            actionSetView = CreateView<ActionSetView>();
            attackRangeListView = CreateView<AttackRangeListView>();
            bodyRangeListView = CreateView<BodyRangeListView>();
            frameListView = CreateView<FrameListView>();
            stateListView = CreateView<StateListView>();
            stateSetView = CreateView<StateSetView>();
            menuView = CreateView<MenuView>();
            toolView = CreateView<ToolView>();
            syncAnimationPreviewView = CreateView<SyncAnimationPreviewView>();
            guiDrawer = new SceneGUIDrawer() { win = this };
            //处理快捷键
            quickButtonHandler = new QuickButtonHandler() { win = this };
        }
        /// <summary>
        /// 创建子窗口
        /// </summary>
        /// <typeparam name="T">子窗口类型</typeparam>
        /// <returns>返回实例</returns>
        private T CreateView<T>() where T : IView, new()
        {
            T obj = new T();
            obj.win = this;
            views.Add(obj);
            return obj;
        }

        ~ActionEditorWindow()
        {
        }

        private void Awake()
        {
        }
        /// <summary>
        /// 销毁
        /// </summary>
        private void OnDestroy()
        {
            //销毁所有子窗口
            foreach (var view in views)
            {
                view.OnDestroy();
            }
        }
        /// <summary>
        /// 使能
        /// </summary>
        private void OnEnable()
        {
            ///设置标题
            this.titleContent = new GUIContent("动作编辑器");

            //加载当前编辑器状态数据
            string data = EditorUserSettings.GetConfigValue(settingPath);
            if (!string.IsNullOrEmpty(data))
            {
                EditorJsonUtility.FromJsonOverwrite(data, setting);
            }
            
            //重绘
            autoRepaintOnSceneChange = true;
            //场景gui回调
            SceneView.duringSceneGui += OnSceneGUI;
            //模式改变回调
            EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
            //加载配置数据到config
            if (config == null && configAsset != null)
            {
                UpdateConfig(configAsset);
            }
            //加载配置数据到config
            if (sysConfig == null && sysConfigAsset != null)
            {
                UpdateSysConfig(sysConfigAsset);
            }
            
        }
        /// <summary>
        /// 失能
        /// </summary>
        private void OnDisable()
        {
            //取消回调注册
            SceneView.duringSceneGui -= OnSceneGUI;
            EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;

            //保存当前编辑器状态数据
            string data = EditorJsonUtility.ToJson(setting, false);
            EditorUserSettings.SetConfigValue(settingPath, data);
        }
        /// <summary>
        /// 运行模式改变回调
        /// </summary>
        /// <param name="state"></param>
        private void OnPlayModeStateChanged(PlayModeStateChange state)
        {
            switch (state)
            {
                case PlayModeStateChange.EnteredPlayMode:
                    actionMachineObj = null;
                    actionMachine = null;
                    configAsset = null;
                    config = null;
                    break;

                case PlayModeStateChange.EnteredEditMode:
                    //还原最后的选择
                    GameObject obj;
                    StateMachineTool amTest;
                    if (!string.IsNullOrEmpty(lastEditorTargetPath)
                        && (obj = GameObject.Find(lastEditorTargetPath)) != null
                        && (amTest = obj.GetComponent<StateMachineTool>()) != null)
                    {
                        UpdateTarget(obj);
                        UpdateConfig(amTest.SMConfig);
                    }
                    lastEditorTargetPath = string.Empty;
                    break;

                case PlayModeStateChange.ExitingEditMode:
                    //记录最后的选择
                    lastEditorTargetPath = actionMachineObj?.GetScenePath();
                    break;
            }
        }

        /// <summary>
        /// 绘制页面
        /// </summary>
        protected virtual void OnGUI()
        {
            //检测数据
            Check();
            //Undo.RecordObject(this, "ActionEditorWindow");

            //绘制所有窗口
            Draw();

            //更新角色的动作
            UpdateActionMachine();

            //什么也没做
            EventProcess();
            //处理快捷键
            quickButtonHandler.OnGUI();
            //重新绘制
            Repaint();
        }
        /// <summary>
        /// 处理gui事件，但是似乎没有用
        /// </summary>
        private void EventProcess()
        {
            Rect rect = position;

            Event evt = Event.current;
            if (!rect.Contains(Event.current.mousePosition))
            {
                return;
            }
        }
        /// <summary>
        /// 检测数据是否正确
        /// </summary>
        private void Check()
        {
            if (!isActionMachineValid)
            {
                actionMachineObj = null;
                actionMachine = null;
                animator = null;
                animaCache = null;
            }

            if (!isConfigValid)
            {
                configAsset = null;
                config = null;
            }
            //导入素材
            if(sysConfigAsset==null)
            {
                if (sysConfigAsset == null)
                {
                    sysConfigAsset = AssetDatabase.LoadAssetAtPath(setting.actionSystemConfigPath, typeof(TextAsset)) as TextAsset;
                }
                UpdateSysConfig(sysConfigAsset);
            }
            //更新标题
            //this.titleContent = new GUIContent(configAsset != null ? $"编辑 {configAsset.name} " : $"动作编辑器");
        }
        /// <summary>
        /// 拿到动作的对象
        /// </summary>
        /// <param name="target"></param>
        public void UpdateTarget(GameObject target)
        {
            if (target == null)
            {
                throw new RuntimeException($"未选择目标");
            }
            actionMachineObj = target;
            actionMachine = target.GetComponent<StateMachineTool>();
            if (actionMachine == null)
            {
                actionMachineObj = null;
                throw new RuntimeException($"目标不存在{nameof(StateMachineTool)}脚本");
            }
            animator = GetAnimator();
            UpdateAnimationAssets();
            UpdateSlot();
        }
        /// <summary>
        /// 加载action配置数据，转为MachineConfig，并保存到config
        /// </summary>
        /// <param name="config"></param>
        public void UpdateConfig(TextAsset config)
        {
            if (config == null)
            {
                throw new RuntimeException($"未选择配置资源");
            }

            this.configAsset = config;
            this.config = DataUtility.FromJson<MachineConfig>(config.text);            
            if (this.config == null)
            {
                throw new RuntimeException($"配置资源解析失败");
            }            
            
        }
        /// <summary>
        /// 加载系统配置数据，转为ActionSystemConfig，并保存到sysConfig
        /// </summary>
        /// <param name="config"></param>
        public void UpdateSysConfig(TextAsset config)
        {
            if (config == null)
            {
                Debug.LogWarning($"未选择配置资源");
                return;
            }

            this.sysConfigAsset = config;
            this.sysConfig = DataUtility.FromJson<ActionSystemConfig>(config.text);
            this.sysConfig.InitInternalData();
            if (this.sysConfig == null)
            {
                Debug.LogWarning($"配置系统资源解析失败");
                return;
            }
            setting.actionSystemConfigPath = AssetDatabase.GetAssetPath(config);
            //更新Pool缓存
            if (sysConfig != null)
            {
                sysConfig.poolItemTypes.Clear();
                var types = TypeCache.GetTypesWithAttribute(typeof(PoolInitAttribute));
                foreach (var type in types)
                {
                    sysConfig.poolItemTypes.Add(type);
                }

            }
        }
        private Dictionary<int, Slot> slotmaps = new Dictionary<int, Slot>();
        public Dictionary<int, Slot> SlotMaps => slotmaps;
        public void UpdateSlot()
        {
            slotmaps.Clear();
            if (actionMachineObj!=null)
            {
                var res = actionMachineObj.GetComponentsInChildren<Slot>();
                foreach (var slot in res)
                {
                    if (!slotmaps.ContainsKey(slot.SlotID))
                    {
                        slotmaps.Add(slot.SlotID, slot);
                    }
                }
            }
        }
        /// <summary>
        /// 场景出现改变
        /// </summary>
        private void Update()
        {            
            foreach (var view in views)
            {
                view.OnUpdate();
            }
        }
        /// <summary>
        /// 场景中绘制
        /// </summary>
        /// <param name="sceneView"></param>
        private void OnSceneGUI(SceneView sceneView)
        {
            if (!isConfigValid || actionMachine == null)
            {
                return;
            }

            //Undo.RecordObject(this, "ActionEditorWindow");

            guiDrawer.OnSceneGUI(sceneView);
            quickButtonHandler.OnSceneGUI(sceneView);

            sceneView.Repaint();
            Repaint();
        }

        #region Anima

        /// <summary>
        /// 更新角色动画
        /// </summary>
        private void UpdateActionMachine()
        {
            
            if (!actionMachineDirty || !isActionMachineValid)
            {
                return;
            }
            actionMachineDirty = false;
            animaCache = null;
            UpdateAnimation();
            UpdateSyncObjcteAnimation();
        }
        AnimationClip animaCache = null;
        Animator animator=null;
        public bool UseAnimationClip
        {
            get
            {
                if(animator==null||animator.runtimeAnimatorController!=null)
                {
                    return false;
                }else
                {
                    return true;
                }
            }

        }

        /// <summary>
        /// 更新场景中角色的动作
        /// </summary>
        private void UpdateAnimation()
        {
            animator = GetAnimator();
            
            int frameIndex = frameSelectIndex;
            if (frameIndex < 0||animator==null)
            {
                return;
            }
            float time = (frameIndex + 1) * FrameTime;
            //使用animator
            if (animator.runtimeAnimatorController!=null)
            {
                string animName = GetAnimationName();
                if (!string.IsNullOrEmpty(animName))
                {
                    animator.PlayInFixedTime(animName,0);
                    float length = animator.GetCurrentAnimatorStateInfo(0).length;
                    float nt = animator.GetCurrentAnimatorStateInfo(0).normalizedTime;
                    animator.Update(-length*nt);//回到原点
                    animator.Update(time);
                }
            }else
            {
                AnimationClip clip = GetCurrentAnimationClip();
                if (clip == null)
                {
                    return;
                }
                //得到具体动作
                clip.SampleAnimation(animator.gameObject, time);
            }
            if(actionMachine!=null&&actionMachine.useRootMotion==false&&actionMachine.rootBone!=null)
            {
                actionMachine.rootBone.localPosition = Vector3.zero;
                actionMachine.rootBone.localRotation = Quaternion.identity;
            }
        }
        #region 其他角色同步播放动画
        List<AnimationClip> syncClips = new List<AnimationClip>();
        List<Animator> syncAnimators = new List<Animator>();
        /// <summary>
        /// 更新需要同步的异步角色动画
        /// </summary>
        private void UpdateSyncObjcteAnimation()
        {
            // 从缓存中获取异步物体动画
            List<AnimationClip> GetSyncAnimationClips()
            {
                syncClips.Clear();
                foreach (var name in syncAnimationNames)
                {
                    if (animations.ContainsKey(name))
                        syncClips.Add(animations[name]);
                    else
                        syncClips.Add(null);
                }
                return syncClips;
            }
            // 获取异步角色的animator
            List<Animator> GetSyncAnimators()
            {
                syncAnimators.Clear();
                foreach (var obj in syncAnimationObjcts)
                {
                    if (obj == null)
                    {
                        continue;
                    }
                    Animator animator = obj.GetComponent<Animator>();
                    if (null != animator)
                    {
                        syncAnimators.Add(animator);
                        continue;
                    }

                    animator = actionMachineObj.GetComponentInChildren<Animator>();

                    syncAnimators.Add(animator);
                    
                }
                return syncAnimators;
            }


            List<AnimationClip> clips = GetSyncAnimationClips();
            int frameIndex = frameSelectIndex;
            if (frameIndex < 0 || animator == null)
            {
                return;
            }
            float time = (frameIndex + 1) * FrameTime;

            List<Animator> animators = GetSyncAnimators();
            if (animators == null || animators.Count != clips.Count)
            {
                return;
            }
            for (int i = 0; i < clips.Count; i++)
            {

                var animator = animators[i];
                if (animator == null)
                {
                    continue;
                }
                if (animator.runtimeAnimatorController != null)
                {
                    string animName = syncAnimationNames[i];
                    if (!string.IsNullOrEmpty(animName))
                    {
                        animator.PlayInFixedTime(animName, 0);
                        float length = animator.GetCurrentAnimatorStateInfo(0).length;
                        float nt = animator.GetCurrentAnimatorStateInfo(0).normalizedTime;
                        animator.Update(-length * nt);//回到原点
                        animator.Update(time);
                    }
                }
                else
                {
                    var clip = clips[i];
                    if (clip != null)
                    {
                        clip.SampleAnimation(animator.gameObject, time);
                    }
                    else
                    {
                        continue;
                    }
                }
                if (actionMachine != null)
                {
                    if (actionMachine.useRootMotion == false && syncAnimationObjctsRootBones[i] != null)
                    {
                        syncAnimationObjctsRootBones[i].localPosition = Vector3.zero;
                        syncAnimationObjctsRootBones[i].localRotation = Quaternion.identity;
                    }
                }
            }
        }
        #endregion
        /// <summary>
        /// 拿到animator
        /// </summary>
        /// <returns></returns>
        private Animator GetAnimator()
        {
            if (null == actionMachineObj)
            {
                return null;
            }
            Animator animator = actionMachineObj.GetComponent<Animator>();
            if (null != animator)
            {
                return animator;
            }

            animator = actionMachineObj.GetComponentInChildren<Animator>();

            return animator;
        }
        /// <summary>
        /// 拿到角色当前状态的动画
        /// </summary>
        /// <returns></returns>
        public AnimationClip GetCurrentAnimationClip()
        {
            if(animaCache==null&&animator!=null)
            {
                var state = currentState;
                if (animator != null && state != null)
                {
                    var animName = GetAnimationName();
                    if (animator.runtimeAnimatorController!=null)
                    {
                        //根据Animator状态机获取动画则返回这个状态机的第一个动画
                        if (!string.IsNullOrEmpty(animName))
                        {
                            //当前状态的第一个动画
                            var anims = animator.GetCurrentAnimatorClipInfo(0);
                            if(anims.Length>0)
                            {
                                animaCache = anims[0].clip;
                            }
                            
                            //var res = Array.Find(animator.runtimeAnimatorController.animationClips, t => string.Compare(animName, t.name) == 0);
                            //if (res != null)
                            //{
                            //    animaCache = res;
                            //}
                        }
                    }else
                    {
                        //从地址获取动画
                        if (!string.IsNullOrEmpty(animName))
                        {
                            animations.TryGetValue(animName,out animaCache);
                        }
                    }                                        
                }
            }            
            return animaCache;
        }
        //当前状态的第一个动画
        Dictionary<string,AnimationClip> animations = new Dictionary<string, AnimationClip>();
        


        public void UpdateAnimationAssets()
        {
            if(!UseAnimationClip)
            {
                return;
            }
            if(!setting.aniamtionPath.StartsWith("Assets/"))
            {
                return;
            }
            animaCache = null;
            animations.Clear();
            
            if(string.IsNullOrEmpty(setting.aniamtionPath))
            {
                return;
            }
            
            string[] results = UnityEditor.AssetDatabase.FindAssets("t:animation", new string[] { setting.aniamtionPath });//拿到资源                 
            if (results.Length > 0)
            {                
                for (int i = 0; i < results.Length; i++)
                {
                    string path = UnityEditor.AssetDatabase.GUIDToAssetPath(results[i]);
                    
                    //var rootAsset = UnityEditor.AssetDatabase.LoadAssetAtPath(path, typeof(AnimationClip)) as AnimationClip;
                    //if (rootAsset != null)
                    //{                        
                    //    if (!animations.ContainsKey(rootAsset.name))
                    //        animations.Add(rootAsset.name,rootAsset);
                    //    //continue;
                    //}
                    //拿到改素材下的所有资源
                    var assetRepresentationsAtPath = UnityEditor.AssetDatabase.LoadAllAssetRepresentationsAtPath(path);
                    //遍历所有资源
                    foreach (var assetRepresentation in assetRepresentationsAtPath)
                    {                        
                        //拿到动画
                        var anim = assetRepresentation as AnimationClip;
                        if (anim != null)
                        {                            
                            if (!animations.ContainsKey(anim.name))
                            {
                                animations.Add(anim.name, anim);
                            }
                                
                        }
                    }
                }
            }
        }
        List<FieldInfo> allStateFields = new List<FieldInfo>();
        private string GetAnimationName()
        {
            var state = currentState;
            if (state != null)
            {
                //变量当filed
                allStateFields.Clear();                
                Type type = state.state.GetType();                
                while(type!=typeof(object))
                {
                    allStateFields.AddRange(type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly));
                    type = type.BaseType;
                }
                FieldInfo[] fields = allStateFields.ToArray();                
                foreach (var f in fields)
                {                    
                    if (f.GetCustomAttribute<AnimationNameAttribute>() != null)
                    {
                        var v = f.GetValue(state.state);
                        if (v == null)
                        {
                            continue;
                        }
                        string animName = v.ToString();                        
                        return animName;
                    }
                }
            }
            return null;
        }
        #endregion Anima

        #region Draw view

        private static string copyData;
        private static Type copyDataType;
        /// <summary>
        /// 拷贝配置
        /// </summary>
        public object copyBuffer
        {
            set
            {
                if (value == null)
                {
                    copyDataType = null;
                    copyData = null;
                    return;
                }
                copyDataType = value.GetType();
                copyData = DataUtility.ToJson(value, copyDataType);
            }
            get
            {
                if (copyDataType == null || copyData == null) { return null; }
                return DataUtility.FromJson(copyData, copyDataType);
            }
        }
        /// <summary>
        /// 绘制
        /// </summary>
        private void Draw()
        {
            #region calc size
            #region 拿到当前工具窗口的大小
            Rect rect = this.position;
            rect.position = Vector2.zero;
            #endregion
            //起始位置，（0,0）
            float startPosX = rect.x;
            float startPosY = rect.y;
            //大小，窗口大小
            float height = rect.height;
            float width = rect.width;
            #region 每一个窗口的初始大小
            Rect menuViewRect = Rect.zero;
            Rect toolViewRect = Rect.zero;
            Rect globalActionListViewRect = Rect.zero;
            Rect globalActionSetViewRect = Rect.zero;
            Rect stateGroupListViewRect = Rect.zero;
            Rect stateGroupSetViewRect = Rect.zero;
            Rect stateListViewRect = Rect.zero;
            Rect frameListViewRect = Rect.zero;
            Rect bodyRangeListViewRect = Rect.zero;
            Rect attackRangeListViewRect = Rect.zero;
            Rect actionSetViewRect = Rect.zero;
            Rect actionListViewRect = Rect.zero;
            Rect stateSetViewRect = Rect.zero;
            Rect syncAnimationPreviewViewRect = Rect.zero;
            #endregion

            //设置菜单栏大小和位置
            menuViewRect = new Rect(
               startPosX + space,
               startPosY + space,
               rect.width - space,
               menuViewRectHeight - space);
            //更新y
            startPosY += menuViewRectHeight;
            //更新高度
            height -= menuViewRectHeight;

            #region 全局Action窗口
            if ((setting.showView & ViewType.PassiveAction) != 0)
            {
                if (!globalActionListView.isPop)
                {
                    globalActionListViewRect = new Rect(
                       startPosX + space,
                       startPosY + space,
                       globalActionListViewRectWidth - space,
                       height - space * 2);
                    startPosX += globalActionListViewRectWidth;
                    width -= globalActionListViewRectWidth;
                }

                if (!globalActionSetView.isPop)
                {
                    globalActionSetViewRect = new Rect(
                       startPosX + space,
                       startPosY + space,
                       globalActionSetViewRectWidth - space,
                       height - space * 2);
                    startPosX += globalActionSetViewRectWidth;
                    width -= globalActionSetViewRectWidth;
                }
            }
            #endregion
            #region Group窗口
            if ((setting.showView & ViewType.StateGroup) != 0)
            {
                if (!stateGroupListView.isPop)
                {
                    stateGroupListViewRect = new Rect(
                       startPosX + space,
                       startPosY + space,
                       stateGroupListViewRectWidth - space,
                       height - space * 2);
                    startPosX += stateGroupListViewRectWidth;
                    width -= stateGroupListViewRectWidth;
                }

                
            }
            #endregion

            #region 状态设置窗口
            if ((setting.showView & ViewType.State) != 0 && !stateListView.isPop)
            {
                stateListViewRect = new Rect(
               startPosX + space,
               startPosY + space,
               stateListViewRectWidth - space,
               height - space * 2);
                startPosX += stateListViewRectWidth;
                width -= stateListViewRectWidth;
            }
            #endregion

            #region 帧配置窗口
            if ((setting.showView & ViewType.Frame) != 0 && !frameListView.isPop)
            {
                frameListViewRect = new Rect(
                   startPosX + space,
                   startPosY + space,
                   width - space,
                    frameListViewRectHeight - space);
                startPosY += frameListViewRectHeight;
                height -= frameListViewRectHeight;
            }
            #endregion

            //滚动窗口
            float itemHeight = height - scrollHeight;
            float nextPosX = startPosX;
            float nextPosY = startPosY;
            bool hasNextView = false;
            #region 组设置
            if ((setting.showView & ViewType.StateGroupSet) != 0 && !stateGroupSetView.isPop)
            {
                stateGroupSetViewRect = new Rect(
                    nextPosX + space,
                    nextPosY + space,
                    stateGroupSetViewRectWidth - space,
                    itemHeight - space * 2);
                nextPosX += stateGroupSetViewRectWidth;
                hasNextView = true;
            }
            #endregion
            #region 工具窗口
            if ((setting.showView & ViewType.Tool) != 0 && !toolView.isPop)
            {
                toolViewRect = new Rect(
                    nextPosX + space,
                    nextPosY + space,
                    toolViewRectWidth - space,
                    itemHeight - space * 2);
                nextPosX += toolViewRectWidth;
                hasNextView = true;
            }
            #endregion

            #region 工具状态集合
            if ((setting.showView & ViewType.StateSet) != 0 && !stateSetView.isPop)
            {
                stateSetViewRect = new Rect(
                    nextPosX + space,
                    nextPosY + space,
                    stateSetViewRectWidth - space,
                    itemHeight - space * 2);
                nextPosX += stateSetViewRectWidth;
                hasNextView = true;
            }
            #endregion

            #region Action设置窗口
            if ((setting.showView & ViewType.Action) != 0)
            {
                if (!actionListView.isPop)
                {
                    actionListViewRect = new Rect(
                        nextPosX + space,
                        nextPosY + space,
                        actionListViewRectWidth - space,
                        itemHeight - space * 2);
                    nextPosX += actionListViewRectWidth;
                    hasNextView = true;
                }

                if (!actionSetView.isPop)
                {
                    actionSetViewRect = new Rect(
                        nextPosX + space,
                        nextPosY + space,
                        actionSetViewRectWidth - space,
                        itemHeight - space * 2);
                    nextPosX += actionSetViewRectWidth;
                    hasNextView = true;
                }
            }
            #endregion
            #region 异步动画
            if ((setting.showView & ViewType.SyncAnimationPreviewSet) != 0)
            {
                if (!syncAnimationPreviewView.isPop)
                {
                    syncAnimationPreviewViewRect = new Rect(
                        nextPosX + space,
                        nextPosY + space,
                        syncAnimationPrewiewViewRectWidth - space,
                        itemHeight - space * 2);
                    nextPosX += syncAnimationPrewiewViewRectWidth;
                    hasNextView = true;
                }
            }
            #endregion
            #region 其他
            if ((setting.showView & ViewType.Other) != 0)
            {
                if (!attackRangeListView.isPop)
                {
                    attackRangeListViewRect = new Rect(
                        nextPosX + space,
                        nextPosY + space,
                        attackRangeListViewRectWidth - space,
                        itemHeight - space * 2);
                    nextPosX += attackRangeListViewRectWidth;
                    hasNextView = true;
                }

                if (!bodyRangeListView.isPop)
                {
                    bodyRangeListViewRect = new Rect(
                        nextPosX + space,
                        nextPosY + space,
                        bodyRangeListViewRectWidth - space,
                        itemHeight - space * 2);
                    nextPosX += bodyRangeListViewRectWidth;
                    hasNextView = true;
                }
            }
            #endregion

            #endregion calc size

            #region draw

            menuView.Draw(menuViewRect);

            if ((setting.showView & ViewType.Frame) != 0 && !frameListView.isPop)
            {
                frameListViewRect.height += hasNextView ? 0 : (height - space);
                frameListView.Draw(frameListViewRect);
            }

            if ((setting.showView & ViewType.State) != 0 && !stateListView.isPop)
            {
                stateListView.Draw(stateListViewRect);
            }
            if ((setting.showView & ViewType.StateGroup) != 0 && !stateGroupListView.isPop)
            {
                stateGroupListView.Draw(stateGroupListViewRect);
            }
            if ((setting.showView & ViewType.PassiveAction) != 0)
            {
                if (!globalActionSetView.isPop)
                {
                    globalActionSetView.Draw(globalActionSetViewRect);
                }
                if (!globalActionListView.isPop)
                {
                    globalActionListView.Draw(globalActionListViewRect);
                }
            }
            if ((setting.showView & ViewType.StateGroup) != 0)
            {
                //if (!stateGroupSetView.isPop)
                //{
                //    stateGroupSetView.Draw(stateGroupSetViewRect);
                //}
                if (!stateGroupListView.isPop)
                {
                    stateGroupListView.Draw(stateGroupListViewRect);
                }
            }

            if (hasNextView)
            {
                Rect position = new Rect(startPosX + space, startPosY, width - space, height);
                Rect view = new Rect(startPosX + space, startPosY, nextPosX - startPosX - space, itemHeight);
                setting.otherViewScrollPos = GUI.BeginScrollView(position, setting.otherViewScrollPos, view, true, false);

                if ((setting.showView & ViewType.StateSet) != 0 && !stateSetView.isPop)
                {
                    stateSetView.Draw(stateSetViewRect);
                }
                if ((setting.showView & ViewType.StateGroupSet) != 0 && !stateGroupSetView.isPop)
                {
                    stateGroupSetView.Draw(stateGroupSetViewRect);
                }
                if ((setting.showView & ViewType.Tool) != 0 && !toolView.isPop)
                {
                    toolView.Draw(toolViewRect);
                }

                if ((setting.showView & ViewType.Action) != 0)
                {
                    if (!actionListView.isPop)
                    {
                        actionListView.Draw(actionListViewRect);
                    }
                    if (!actionSetView.isPop)
                    {
                        actionSetView.Draw(actionSetViewRect);
                    }
                }

                if ((setting.showView & ViewType.Other) != 0)
                {
                    if (!attackRangeListView.isPop)
                    {
                        attackRangeListView.Draw(attackRangeListViewRect);
                    }
                    if (!bodyRangeListView.isPop)
                    {
                        bodyRangeListView.Draw(bodyRangeListViewRect);
                    }
                    if (!syncAnimationPreviewView.isPop)
                    {
                        syncAnimationPreviewView.Draw(syncAnimationPreviewViewRect);
                    }
                }
                GUI.EndScrollView();
            }

            #endregion draw
        }

        #endregion Draw view

        #region 配合StateUIDAttribute
        List<int> _stateIDs = new List<int>();
        public List<int> GetStateUID()
        {
            _stateIDs.Clear();
            _stateIDs.Add(BaseState.UNKNOWN_UID);
            if(config!=null)
            {
                foreach(var si in config.states)
                {
                    if(si.state!=null)
                    _stateIDs.Add((si.state as BaseState).UID);
                }
            }
            return _stateIDs;
        }
        List<string> _stateNames = new List<string>();
        public List<string> GetStateNames()
        {
            _stateNames.Clear();
            _stateNames.Add("未知状态");
            if (config != null)
            {
                foreach (var si in config.states)
                {
                    if(si.GID==StateGroup.NoGroup)
                    {
                        _stateNames.Add((si.state as BaseState).StateName);
                    }
                    else
                    {
                        string groupName = "未知组";
                        for (int gi = 0; gi < config.groups.Count; gi++)
                        {
                            if (config.groups[gi].GID == si.GID)
                            {
                                groupName = config.groups[gi].GroupName;
                                break;
                            }
                        }

                        _stateNames.Add(groupName+ "/" + (si.state as BaseState).StateName);
                    }
                    
                }
            }
            return _stateNames;
        }
        #endregion
        #region 状态组
        List<int> _groupIDs = new List<int>();
        public List<int> GetGroupGID()
        {
            _groupIDs.Clear();
            _groupIDs.Add(StateGroup.NoGroup);
            if (config != null)
            {
                foreach (var gi in config.groups)
                {
                    _groupIDs.Add(gi.GID);
                }
            }
            return _groupIDs;
        }
        List<string> _groupNames = new List<string>();
        public List<string> GetGroupNames()
        {
            _groupNames.Clear();
            _groupNames.Add("No Group");
            if (config != null)
            {
                foreach (var gi in config.groups)
                {
                    _groupNames.Add(gi.GroupName);
                }
            }
            return _groupNames;
        }
        #endregion
    }
    /// <summary>
    /// 弹窗
    /// </summary>
    public class ViewWindow : EditorWindow
    {
        protected IView _view;
        protected ActionEditorWindow _win;
        protected string _viewTypeName;
        /// <summary>
        /// 当前弹窗对应的view
        /// </summary>
        public IView view
        {
            get
            {
                if (_view != null && _win != null) { return _view; }

                Type viewType = Type.GetType(_viewTypeName, false);
                if (viewType == null) { return null; }

                if (!HasOpenInstances<ActionEditorWindow>()) { return null; }

                _win = GetWindow<ActionEditorWindow>();
                _view = _win.views.Find(t => t.GetType() == viewType);
                _view.popWindow = this;
                return _view;
            }
            set
            {
                _view = value;
                _win = value.win;
                _viewTypeName = value.GetType().FullName + "," + value.GetType().Assembly.FullName;
                _view.popWindow = this;
            }
        }
        /// <summary>
        /// 弹窗绘制
        /// </summary>
        /// <param name="view">当前需要绘制的view</param>
        /// <param name="rect">当前弹窗的位置</param>
        /// <returns></returns>
        public static ViewWindow Show(IView view, Rect rect)
        {
            var win = EditorWindow.CreateWindow<ViewWindow>(view.title);
            win.position = rect;
            win.view = view;
            win.Show();
            return win;
        }

        private void OnEnable()
        {
            autoRepaintOnSceneChange = true;
            
        }

        private void OnDisable()
        {
        }

        private void OnDestroy()
        {
            view?.OnPopDestroy();
        }
        /// <summary>
        /// 绘制
        /// </summary>
        private void OnGUI()
        {
            if (view == null)
            {
                return;
            }

            Rect contentRect = new Rect(Vector2.zero, this.position.size);
            view.Draw(contentRect);

            Repaint();
        }
    }
}